package org.xx.armory.swing.components.formatters;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xx.armory.swing.components.PrefixSuffixNavigationFilter;

import javax.swing.text.NavigationFilter;
import java.text.ParseException;

import static org.xx.armory.commons.Validators.notNull;

public abstract class AbstractTextFormatter
        extends javax.swing.text.DefaultFormatter {
    private final Logger logger = LoggerFactory.getLogger(AbstractTextFormatter.class);

    private final String prefix;
    private final String suffix;

    protected AbstractTextFormatter(
            String prefix,
            String suffix
    ) {
        this.prefix = notNull(prefix, "prefix");
        this.suffix = notNull(suffix, "suffix");

    }

    public final String getPrefix() {
        return this.prefix;
    }

    public final String getSuffix() {
        return this.suffix;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final Object stringToValue(
            String text
    )
            throws ParseException {
        if (text.startsWith(getPrefix())) {
            text = text.substring(getPrefix().length());
        }
        if (text.endsWith(getSuffix())) {
            text = text.substring(0, text.length() - getSuffix().length());
        }

        final Object value = stringToValue2(text);

        logger.trace("text[{}] to value[{}]", text, value);

        return value;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final String valueToString(
            Object value
    ) {
        String text = valueToString2(value);
        if (!text.startsWith(getPrefix())) {
            text = getPrefix() + text;
        }
        if (!text.endsWith(getSuffix())) {
            text = text + getSuffix();
        }

        logger.trace("value[{}] to text[{}]", value, text);

        return text;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected NavigationFilter getNavigationFilter() {
        return new PrefixSuffixNavigationFilter(
                getFormattedTextField(),
                getPrefix().length(),
                getSuffix().length()
        );
    }

    protected abstract String valueToString2(
            Object value
    );

    protected abstract Object stringToValue2(
            String text
    )
            throws ParseException;
}
